Mestre Reacts useImperativeHandle-hook: Tilpass refs, eksponer komponent-API-er, og bygg gjenbrukbare, vedlikeholdbare komponenter for globale webapplikasjoner.
React useImperativeHandle: Tilpasning av Refs og Eksponering av API
I det dynamiske landskapet av front-end-utvikling har React blitt et kraftig verktøy for å bygge interaktive og engasjerende brukergrensesnitt. Blant de mange funksjonene tilbyr Reacts ref-system en måte å samhandle direkte med DOM-noder eller React-komponentinstanser. Noen ganger trenger vi imidlertid mer kontroll over hva en komponent eksponerer for omverdenen. Det er her useImperativeHandle kommer inn, som lar oss tilpasse ref-en og eksponere et spesifikt API for ekstern bruk. Denne guiden vil dykke ned i detaljene rundt useImperativeHandle og gi deg en omfattende forståelse av bruken, fordelene og praktiske anvendelser for å bygge robuste og vedlikeholdbare globale webapplikasjoner.
Forståelse av React Refs
Før vi dykker ned i useImperativeHandle, er det avgjørende å forstå grunnleggende om React refs. Refs, en forkortelse for referanser, gir en måte å få tilgang til og manipulere DOM-noder eller React-komponentinstanser direkte. De er spesielt nyttige når du trenger å:
- Samhandle med DOM-elementer (f.eks. sette fokus på et input-felt, måle dimensjonene til et element).
- Kalle metoder på en komponentinstans.
- Håndtere integrasjoner med tredjepartsbiblioteker som krever direkte DOM-manipulasjon.
Refs kan opprettes ved hjelp av useRef-hooken. Denne hooken returnerer et muterbart ref-objekt der .current-egenskapen initialiseres til argumentet som sendes inn (null hvis ingen argument sendes inn). Ref-objektet vedvarer på tvers av re-rendringer, slik at du kan lagre og få tilgang til verdier gjennom hele komponentens livssyklus.
Eksempel: Bruke useRef til å sette fokus på et input-felt:
import React, { useRef, useEffect } from 'react';
function MyInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return (
<input type="text" ref={inputRef} />
);
}
I dette eksempelet er inputRef knyttet til input-elementet ved hjelp av ref-propen. useEffect-hooken sikrer at input-feltet får fokus når komponenten monteres. Dette demonstrerer en grunnleggende bruk av refs for direkte DOM-manipulasjon.
Rollen til useImperativeHandle
Selv om refs gir tilgang til komponenter, kan de eksponere hele komponentinstansen, inkludert intern tilstand og metoder som ikke bør være tilgjengelige utenfra. useImperativeHandle gir en måte å kontrollere hva foreldrekomponenten har tilgang til. Det lar deg tilpasse ref-objektet som eksponeres for forelderen, og dermed effektivt skape et offentlig API for komponenten din.
Slik fungerer useImperativeHandle:
- Tar tre argumenter: Ref-en som skal tilpasses, en funksjon som returnerer et objekt som representerer ref-ens API, og en avhengighetsliste (lignende
useEffect). - Tilpasser ref-en: Funksjonen du gir til
useImperativeHandlebestemmer hva ref-objektet skal inneholde. Dette lar deg selektivt eksponere metoder og egenskaper, og skjermer dermed de interne mekanismene i komponenten din. - Forbedrer innkapsling: Ved å nøye kuratere ref-ens API, forbedrer du innkapslingen og gjør komponenten din enklere å vedlikeholde og forstå. Endringer i intern tilstand har mindre sannsynlighet for å påvirke komponentens offentlige API.
- Muliggjør gjenbrukbarhet: Et veldefinert offentlig API forenkler gjenbruk av komponenter på tvers av ulike deler av applikasjonen din, eller til og med i helt nye prosjekter.
Syntaks:
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
const MyComponent = forwardRef((props, ref) => {
const internalState = // ...
useImperativeHandle(ref, () => ({
// Metoder og egenskaper som skal eksponeres
method1: () => { /* ... */ },
property1: internalState // eller en avledet verdi
}), [/* avhengigheter */]);
return (
<div> {/* ... */} </div>
);
});
Nøkkelelementer i syntaksen:
forwardRef: Dette er en høyere-ordens komponent som lar komponenten din akseptere en ref. Den gir det andre argumentet (ref) til komponentfunksjonen din.useImperativeHandle(ref, createHandle, [deps]): Det er i denne hooken magien skjer. Du sender inn ref-en som er gitt avforwardRef.createHandleer en funksjon som returnerer objektet som inneholder det offentlige API-et. Avhengighetslisten ([deps]) bestemmer når API-et blir gjenskapt.
Praktiske eksempler på useImperativeHandle
La oss utforske noen praktiske scenarioer der useImperativeHandle virkelig skinner. Vi vil bruke eksempler som er relevante for et mangfoldig internasjonalt publikum.
1. Eksponere et offentlig API for en tilpasset modal-komponent
Se for deg at du bygger en gjenbrukbar modal-komponent. Du ønsker å la foreldrekomponenter kontrollere modalens synlighet (vis/skjul) og potensielt utløse andre handlinger. Dette er et perfekt bruksområde for useImperativeHandle.
import React, { forwardRef, useImperativeHandle, useState } from 'react';
const Modal = forwardRef((props, ref) => {
const [isOpen, setIsOpen] = useState(false);
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
useImperativeHandle(ref, () => ({
open: openModal,
close: closeModal,
isOpen: isOpen, // Eksponer den nåværende tilstanden
// Du kan legge til metoder for animasjon eller andre handlinger her.
}));
return (
<div style={{ display: isOpen ? 'block' : 'none' }}>
<div>Modal Content</div>
<button onClick={closeModal}>Close</button>
</div>
);
});
export default Modal;
Forklaring:
Modal-komponenten brukerforwardReffor å motta en ref.isOpen-tilstanden styrer modalens synlighet.openModal- ogcloseModal-funksjonene håndterer henholdsvis åpning og lukking av modalen.useImperativeHandletilpasser ref-en. Den eksponereropen- ogclose-metoder for å kontrollere modalen fra foreldrekomponenten, sammen med `isOpen`-tilstanden for informasjonsformål.
Bruk i en foreldrekomponent:
import React, { useRef } from 'react';
import Modal from './Modal';
function App() {
const modalRef = useRef(null);
const handleOpenModal = () => {
modalRef.current.open();
};
const handleCloseModal = () => {
modalRef.current.close();
};
return (
<div>
<button onClick={handleOpenModal}>Open Modal</button>
<Modal ref={modalRef} />
<button onClick={handleCloseModal}>Close Modal (via ref)</button>
</div>
);
}
export default App;
I foreldrekomponenten får vi en referanse til Modal-instansen ved hjelp av useRef. Vi bruker deretter de eksponerte open- og close-metodene (definert i useImperativeHandle i Modal-komponenten) for å kontrollere modalens synlighet. Dette skaper et rent og kontrollert API.
2. Lage en tilpasset input-komponent med validering
Tenk deg at du bygger en tilpasset input-komponent som utfører validering. Du ønsker å gi foreldrekomponenten en måte å programmatisk utløse valideringen og hente valideringsstatusen.
import React, { forwardRef, useImperativeHandle, useState } from 'react';
const TextInput = forwardRef((props, ref) => {
const [value, setValue] = useState('');
const [isValid, setIsValid] = useState(true);
const validate = () => {
// Eksempelvalidering (erstatt med din faktiske logikk)
const valid = value.trim().length > 0;
setIsValid(valid);
return valid; // Returnerer valideringsresultatet
};
useImperativeHandle(ref, () => ({
validate: validate,
getValue: () => value,
isValid: isValid,
}));
const handleChange = (event) => {
setValue(event.target.value);
setIsValid(true); // Tilbakestill gyldighet ved endring
};
return (
<div>
<input type="text" value={value} onChange={handleChange} {...props} />
{!isValid && <p style={{ color: 'red' }}>This field is required.</p>}
</div>
);
});
export default TextInput;
Forklaring:
TextInput-komponenten brukerforwardRef.valuelagrer input-verdien.isValidsporer valideringsstatusen.validateutfører valideringslogikken (du kan tilpasse denne basert på internasjonale krav eller spesifikke input-begrensninger). Den returnerer en boolean som representerer valideringsresultatet.useImperativeHandleeksponerervalidate,getValue, ogisValid.handleChangeoppdaterer verdien og tilbakestiller valideringsstatusen ved brukerinput.
Bruk i en foreldrekomponent:
import React, { useRef } from 'react';
import TextInput from './TextInput';
function Form() {
const inputRef = useRef(null);
const handleSubmit = () => {
const isValid = inputRef.current.validate();
if (isValid) {
// Behandle skjemainnsending
console.log('Form submitted!');
} else {
console.log('Form validation failed.');
}
};
return (
<div>
<TextInput ref={inputRef} placeholder="Enter text" />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default Form;
Foreldrekomponenten henter ref-en, kaller validate-metoden på input-komponenten, og handler deretter. Dette eksempelet kan enkelt tilpasses for forskjellige input-typer (f.eks. e-post, telefonnumre) med mer sofistikerte valideringsregler. Vurder å tilpasse valideringsregler til ulike land (f.eks. telefonnummerformater i forskjellige regioner).
3. Implementere en gjenbrukbar skyveknapp-komponent (Slider)
Se for deg en skyveknapp-komponent der foreldrekomponenten trenger å sette verdien programmatisk. Du kan bruke useImperativeHandle for å eksponere en setValue-metode.
import React, { forwardRef, useImperativeHandle, useState } from 'react';
const Slider = forwardRef((props, ref) => {
const [value, setValue] = useState(props.defaultValue || 0);
const handleSliderChange = (event) => {
setValue(parseInt(event.target.value, 10));
};
useImperativeHandle(ref, () => ({
setValue: (newValue) => {
setValue(newValue);
},
getValue: () => value,
}));
return (
<input
type="range"
min={props.min || 0}
max={props.max || 100}
value={value}
onChange={handleSliderChange}
/>
);
});
export default Slider;
Forklaring:
Slider-komponenten brukerforwardRef.value-tilstanden håndterer skyveknappens nåværende verdi.handleSliderChangeoppdaterer verdien når brukeren samhandler med skyveknappen.useImperativeHandleeksponerer ensetValue-metode og en `getValue`-metode for ekstern kontroll.
Bruk i en foreldrekomponent:
import React, { useRef, useEffect } from 'react';
import Slider from './Slider';
function App() {
const sliderRef = useRef(null);
useEffect(() => {
// Sett skyveknappens verdi til 50 etter at komponenten monteres
if (sliderRef.current) {
sliderRef.current.setValue(50);
}
}, []);
const handleButtonClick = () => {
// Hent skyveknappens nåværende verdi
const currentValue = sliderRef.current.getValue();
console.log("Current slider value:", currentValue);
};
return (
<div>
<Slider ref={sliderRef} min={0} max={100} defaultValue={25} />
<button onClick={handleButtonClick}>Get Current Value</button>
</div>
);
}
export default App;
Foreldrekomponenten kan programmatisk sette skyveknappens verdi ved hjelp av sliderRef.current.setValue(50) og hente den nåværende verdien med `sliderRef.current.getValue()`. Dette gir et tydelig og kontrollert API, og er anvendelig for andre grafiske komponenter. Eksempelet tillater dynamiske oppdateringer fra server-data eller andre kilder.
Beste praksis og hensyn
Selv om useImperativeHandle er et kraftig verktøy, er det viktig å bruke det med omhu og følge beste praksis for å opprettholde kodens klarhet og forhindre potensielle problemer.
- Bruk med måte: Unngå overdreven bruk av
useImperativeHandle. Den egner seg best for scenarioer der du trenger å kontrollere en komponent fra dens forelder eller eksponere et spesifikt API. Foretrekk om mulig å bruke props og hendelseshåndterere for å kommunisere mellom komponenter. Overdreven bruk kan føre til mindre vedlikeholdbar kode. - Tydelig API-definisjon: Design API-et du eksponerer med
useImperativeHandlenøye. Velg beskrivende metodenavn og egenskaper for å gjøre det enkelt for andre utviklere (eller deg selv i fremtiden) å forstå hvordan man samhandler med komponenten. Sørg for tydelig dokumentasjon (f.eks. JSDoc-kommentarer) hvis komponenten er en del av et større prosjekt. - Unngå å eksponere for mye: Eksponer kun det som er absolutt nødvendig. Å skjule intern tilstand og metoder forbedrer innkapslingen og reduserer risikoen for utilsiktede endringer fra foreldrekomponenten. Vurder konsekvensene av å endre den interne tilstanden.
- Avhengighetsliste: Vær nøye med avhengighetslisten i
useImperativeHandle. Hvis det eksponerte API-et avhenger av verdier fra props eller state, inkluder dem i avhengighetslisten. Dette sikrer at API-et oppdateres når disse avhengighetene endres. Utelatelse av avhengigheter kan føre til utdaterte verdier eller uventet oppførsel. - Vurder alternativer: I mange tilfeller kan du oppnå ønsket resultat ved hjelp av props og hendelseshåndterere. Før du tyr til
useImperativeHandle, vurder om props og hendelseshåndterere tilbyr en enklere løsning. For eksempel, i stedet for å bruke en ref for å kontrollere synligheten til en modal, kan du sende enisOpen-prop og enonClose-håndterer til modal-komponenten. - Testing: Når du bruker
useImperativeHandle, er det viktig å teste det eksponerte API-et grundig. Sørg for at metodene og egenskapene oppfører seg som forventet og at de ikke introduserer utilsiktede bivirkninger. Skriv enhetstester for å verifisere korrekt oppførsel av API-et. - Tilgjengelighet: Når du designer komponenter som bruker
useImperativeHandle, sørg for at de er tilgjengelige for brukere med nedsatt funksjonsevne. Dette inkluderer å tilby passende ARIA-attributter og sikre at komponenten kan navigeres med tastatur. Vurder internasjonalisering og tilgjengelighetsstandarder for et globalt publikum. - Dokumentasjon: Dokumenter alltid det eksponerte API-et i kodekommentarene dine (f.eks. JSDoc). Beskriv hver metode og egenskap, forklar formålet og eventuelle parametere den aksepterer. Dette vil hjelpe andre utviklere (og ditt fremtidige jeg) å forstå hvordan komponenten skal brukes.
- Komponentkomposisjon: Vurder å komponere mindre, mer fokuserte komponenter i stedet for å bygge monolittiske komponenter som eksponerer omfattende API-er via
useImperativeHandle. Denne tilnærmingen fører ofte til mer vedlikeholdbar og gjenbrukbar kode.
Avanserte bruksområder
Utover de grunnleggende eksemplene har useImperativeHandle mer avanserte anvendelser:
1. Integrasjon med tredjepartsbiblioteker
Mange tredjepartsbiblioteker (f.eks. diagrambiblioteker, kartbiblioteker) krever direkte DOM-manipulasjon eller tilbyr et API du kan kontrollere. useImperativeHandle kan være uvurderlig for å integrere disse bibliotekene i dine React-komponenter.
Eksempel: Integrere et diagrambibliotek
La oss si at du bruker et diagrambibliotek som lar deg oppdatere diagramdataene og tegne diagrammet på nytt. Du kan bruke useImperativeHandle til å eksponere en metode som oppdaterer diagramdataene:
import React, { forwardRef, useImperativeHandle, useEffect, useRef } from 'react';
import ChartLibrary from 'chart-library'; // Antar et diagrambibliotek
const Chart = forwardRef((props, ref) => {
const chartRef = useRef(null);
useEffect(() => {
// Initialiser diagrammet (erstatt med faktisk biblioteksinitialisering)
chartRef.current = new ChartLibrary(document.getElementById('chartCanvas'), props.data);
return () => {
// Rydd opp i diagrammet (f.eks. ødelegg diagraminstansen)
if (chartRef.current) {
chartRef.current.destroy();
}
};
}, [props.data]);
useImperativeHandle(ref, () => ({
updateData: (newData) => {
// Oppdater diagramdata og tegn på nytt (erstatt med bibliotekspesifikke kall)
if (chartRef.current) {
chartRef.current.setData(newData);
chartRef.current.redraw();
}
},
}));
return <canvas id="chartCanvas" width="400" height="300"></canvas>;
});
export default Chart;
I dette scenarioet innkapsler Chart-komponenten diagrambiblioteket. useImperativeHandle eksponerer en updateData-metode, som lar foreldrekomponenten oppdatere diagrammets data og utløse en ny tegning. Dette eksempelet kan kreve tilpasning avhengig av det spesifikke diagrambiblioteket du bruker. Husk å håndtere opprydding av diagrammet når komponenten avmonteres.
2. Bygge tilpassede animasjoner og overganger
Du kan utnytte useImperativeHandle for å kontrollere animasjoner og overganger i en komponent. For eksempel kan du ha en komponent som toner inn eller ut. Du kan eksponere metoder for å utløse inn-/uttoningsanimasjonene.
import React, { forwardRef, useImperativeHandle, useState, useRef, useEffect } from 'react';
const FadeInComponent = forwardRef((props, ref) => {
const [isVisible, setIsVisible] = useState(false);
const elementRef = useRef(null);
useEffect(() => {
// Valgfritt: Innledende synlighet basert på en prop
if (props.initialVisible) {
fadeIn();
}
}, [props.initialVisible]);
const fadeIn = () => {
setIsVisible(true);
};
const fadeOut = () => {
setIsVisible(false);
};
useImperativeHandle(ref, () => ({
fadeIn,
fadeOut,
}));
return (
<div
ref={elementRef}
style={{
opacity: isVisible ? 1 : 0,
transition: 'opacity 0.5s ease-in-out',
}}
>
{props.children}
</div>
);
});
export default FadeInComponent;
Forklaring:
FadeInComponentaksepterer en ref.isVisiblehåndterer synlighetstilstanden.fadeInogfadeOutoppdaterer synligheten.useImperativeHandleeksponererfadeIn- ogfadeOut-metodene.- Komponenten bruker CSS-overganger for inn-/uttoningseffekten.
Bruk i en foreldrekomponent:
import React, { useRef } from 'react';
import FadeInComponent from './FadeInComponent';
function App() {
const fadeInRef = useRef(null);
const handleFadeIn = () => {
fadeInRef.current.fadeIn();
};
const handleFadeOut = () => {
fadeInRef.current.fadeOut();
};
return (
<div>
<FadeInComponent ref={fadeInRef} initialVisible>
<p>This is the fading content.</p>
</FadeInComponent>
<button onClick={handleFadeIn}>Fade In</button>
<button onClick={handleFadeOut}>Fade Out</button>
</div>
);
}
export default App;
Dette eksempelet skaper en gjenbrukbar komponent. Foreldrekomponenten kan kontrollere animasjonen ved hjelp av fadeIn- og fadeOut-metodene som eksponeres via ref-en. Foreldrekomponenten har full kontroll over inn- og uttoningsatferden.
3. Kompleks komponentkomposisjon
Når du bygger komplekse brukergrensesnitt, kan du komponere flere komponenter sammen. useImperativeHandle kan brukes til å lage et offentlig API for en sammensetning av komponenter. Dette lar en forelder samhandle med den sammensatte komponenten som en enkelt enhet.
Eksempel: Komponere et skjema med input-felt
Du kan lage en skjemakomponent som inneholder flere tilpassede input-komponenter. Du vil kanskje eksponere en metode for å validere alle input-feltene eller hente verdiene deres.
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import TextInput from './TextInput'; // Antar TextInput-komponent fra et tidligere eksempel
const Form = forwardRef((props, ref) => {
const input1Ref = useRef(null);
const input2Ref = useRef(null);
const validateForm = () => {
const isValid1 = input1Ref.current.validate();
const isValid2 = input2Ref.current.validate();
return isValid1 && isValid2;
};
const getFormValues = () => ({
field1: input1Ref.current.getValue(),
field2: input2Ref.current.getValue(),
});
useImperativeHandle(ref, () => ({
validate: validateForm,
getValues: getFormValues,
}));
return (
<div>
<TextInput ref={input1Ref} placeholder="Field 1" />
<TextInput ref={input2Ref} placeholder="Field 2" />
</div>
);
});
export default Form;
Forklaring:
Form-komponenten brukerforwardRef.- Den bruker to
TextInput-komponenter (eller andre tilpassede input-komponenter), hver med sin egen ref. validateFormkallervalidate-metoden på hverTextInput-instans.getFormValueshenter verdiene fra hvert input-felt.useImperativeHandleeksponerervalidate- oggetValues-metodene.
Denne strukturen er nyttig når du trenger å bygge skjemaer som har komplekse valideringsregler, eller er høyt tilpasset. Dette er spesielt nyttig hvis applikasjonen må overholde spesifikke valideringsregler på tvers av land og kulturer.
Hensyn til tilgjengelighet og internasjonalisering
Når du bygger komponenter som bruker useImperativeHandle, er tilgjengelighet og internasjonalisering avgjørende, spesielt for et globalt publikum. Vurder følgende:
- ARIA-attributter: Bruk ARIA (Accessible Rich Internet Applications)-attributter for å gi semantisk informasjon om komponentene dine til hjelpeteknologier (f.eks. skjermlesere). Sørg for riktig merking og rolletildelinger for elementer. For eksempel, når du lager en tilpasset modal-komponent, bruk ARIA-attributter som
aria-modal="true"ogaria-labelledby. - Tastaturnavigasjon: Sørg for at alle interaktive elementer i komponenten din er tilgjengelige via tastatur. Brukere skal kunne navigere gjennom komponenten med Tab-tasten og samhandle med elementer ved hjelp av Enter eller mellomromstasten. Vær nøye med tabulatorrekkefølgen i komponenten din.
- Fokusstyring: Håndter fokus på en passende måte, spesielt når komponenter blir synlige eller skjulte. Sørg for at fokus rettes mot det riktige elementet (f.eks. det første interaktive elementet i en modal) når en komponent åpnes, og at det flyttes til et logisk sted når komponenten lukkes.
- Internasjonalisering (i18n): Design komponentene dine slik at de enkelt kan oversettes til forskjellige språk. Bruk internasjonaliseringsbiblioteker (f.eks.
react-i18next) for å håndtere tekstoversettelser og forskjellige dato-, tids- og tallformater. Unngå hardkoding av strenger i komponentene dine og bruk heller oversettelsesnøkler. Husk at noen kulturer leser fra venstre til høyre, mens andre leser fra høyre til venstre. - Lokalisering (l10n): Vurder kulturelle og regionale forskjeller. Dette inkluderer ting som dato- og tidsformater, valutasymboler, adresseformater og telefonnummerformater. Valideringsreglene dine bør være fleksible og tilpasningsdyktige til forskjellige regionale standarder. Tenk på hvordan komponenten din presenterer og behandler informasjon på forskjellige språk.
- Fargekontrast: Sørg for tilstrekkelig fargekontrast mellom tekst og bakgrunnselementer for å oppfylle tilgjengelighetsretningslinjer (f.eks. WCAG). Bruk en fargekontrastsjekker for å verifisere at designene dine er tilgjengelige for brukere med nedsatt synsevne.
- Testing med hjelpeteknologier: Test komponentene dine jevnlig med skjermlesere og andre hjelpeteknologier for å sikre at de er brukbare for personer med nedsatt funksjonsevne. Bruk verktøy som Lighthouse (en del av Chrome DevTools) for å revidere komponentene dine for tilgjengelighetsproblemer.
- RTL-støtte: Hvis du bygger en global applikasjon, støtt høyre-til-venstre (RTL)-språk som arabisk og hebraisk. Dette innebærer mer enn bare å oversette tekst. Det krever justering av layout og retning på komponentene dine. Bruk CSS-egenskaper som
direction: rtlog vurder hvordan du vil håndtere layouten.
Konklusjon
useImperativeHandle er et verdifullt verktøy i verktøykassen til en React-utvikler, som muliggjør tilpasning av refs og kontrollert eksponering av API-er. Ved å forstå prinsippene og anvende beste praksis, kan du bygge mer robuste, vedlikeholdbare og gjenbrukbare React-komponenter. Fra å lage tilpassede modal-komponenter og input-validering til å integrere med tredjepartsbiblioteker og konstruere komplekse brukergrensesnitt, åpner useImperativeHandle en verden av muligheter. Det er imidlertid viktig å bruke denne hooken med omhu, vurdere avveiningene og utforske alternative tilnærminger som props og hendelser når det er hensiktsmessig. Prioriter alltid tydelig API-design, innkapsling og tilgjengelighet for å sikre at komponentene dine er brukervennlige og tilgjengelige for et globalt publikum. Ved å omfavne disse prinsippene kan du skape webapplikasjoner som leverer eksepsjonelle opplevelser for brukere over hele verden. Vurder alltid konteksten til forskjellige kulturer og regioner når du utvikler programvare for et globalt publikum.